module RegisterFile(
  ReadRegister1,
  ReadRegister2,
  WriteRegister,
  WriteData,
  ReadData1,
  ReadData2,
  RegWrite,
  clk,
  rst
);

input [4:0]ReadRegister1, ReadRegister2, WriteRegister;
input [7:0]WriteData;
input RegWrite;
input clk, rst;
output [7:0]ReadData1, ReadData2;

//register setting
wire [7:0]regout0, regout1, regout2, regout3, regout4, regout5, regout6, regout7,
          regout8, regout9, regout10, regout11, regout12, regout13, regout14, regout15,
  	       regout16, regout17, regout18, regout19, regout20, regout21, regout22, regout23,
          regout24, regout25, regout26, regout27, regout28, regout29, regout30, regout31;

//WriteData

wire [31:0]realwrite, tempwrite;

DEC5to32 dec1(WriteRegister, tempwrite);

and rw0(realwrite[0], RegWrite, tempwrite[0]);
and rw1(realwrite[1], RegWrite, tempwrite[1]);
and rw2(realwrite[2], RegWrite, tempwrite[2]);
and rw3(realwrite[3], RegWrite, tempwrite[3]);
and rw4(realwrite[4], RegWrite, tempwrite[4]);
and rw5(realwrite[5], RegWrite, tempwrite[5]);
and rw6(realwrite[6], RegWrite, tempwrite[6]);
and rw7(realwrite[7], RegWrite, tempwrite[7]);
and rw8(realwrite[8], RegWrite, tempwrite[8]);
and rw9(realwrite[9], RegWrite, tempwrite[9]);
and rw10(realwrite[10], RegWrite, tempwrite[10]);
and rw11(realwrite[11], RegWrite, tempwrite[11]);
and rw12(realwrite[12], RegWrite, tempwrite[12]);
and rw13(realwrite[13], RegWrite, tempwrite[13]);
and rw14(realwrite[14], RegWrite, tempwrite[14]);
and rw15(realwrite[15], RegWrite, tempwrite[15]);
and rw16(realwrite[16], RegWrite, tempwrite[16]);
and rw17(realwrite[17], RegWrite, tempwrite[17]);
and rw18(realwrite[18], RegWrite, tempwrite[18]);
and rw19(realwrite[19], RegWrite, tempwrite[19]);
and rw20(realwrite[20], RegWrite, tempwrite[20]);
and rw21(realwrite[21], RegWrite, tempwrite[21]);
and rw22(realwrite[22], RegWrite, tempwrite[22]);
and rw23(realwrite[23], RegWrite, tempwrite[23]);
and rw24(realwrite[24], RegWrite, tempwrite[24]);
and rw25(realwrite[25], RegWrite, tempwrite[25]);
and rw26(realwrite[26], RegWrite, tempwrite[26]);
and rw27(realwrite[27], RegWrite, tempwrite[27]);
and rw28(realwrite[28], RegWrite, tempwrite[28]);
and rw29(realwrite[29], RegWrite, tempwrite[29]);
and rw30(realwrite[30], RegWrite, tempwrite[30]);
and rw31(realwrite[31], RegWrite, tempwrite[31]);



//$zero
Register_8bit R0(clk, rst, 8'b00000000, regout0, 2'b11);
//$at
Register_8bit R1(clk, rst, WriteData, regout1, {realwrite[1], realwrite[1]});
//$v0~$v1
Register_8bit R2(clk, rst, WriteData, regout2, {realwrite[2], realwrite[2]});
Register_8bit R3(clk, rst, WriteData, regout3, {realwrite[3], realwrite[3]});
//$a0~$a3
Register_8bit R4(clk, rst, WriteData, regout4, {realwrite[4], realwrite[4]});
Register_8bit R5(clk, rst, WriteData, regout5, {realwrite[5], realwrite[5]});
Register_8bit R6(clk, rst, WriteData, regout6, {realwrite[6], realwrite[6]});
Register_8bit R7(clk, rst, WriteData, regout7, {realwrite[7], realwrite[7]});
//$t0~$t7
Register_8bit R8(clk, rst, WriteData, regout8, {realwrite[8], realwrite[8]});
Register_8bit R9(clk, rst, WriteData, regout9, {realwrite[9], realwrite[9]});
Register_8bit R10(clk, rst, WriteData, regout10, {realwrite[10], realwrite[10]});
Register_8bit R11(clk, rst, WriteData, regout11, {realwrite[11], realwrite[11]});
Register_8bit R12(clk, rst, WriteData, regout12, {realwrite[12], realwrite[12]});
Register_8bit R13(clk, rst, WriteData, regout13, {realwrite[13], realwrite[13]});
Register_8bit R14(clk, rst, WriteData, regout14, {realwrite[14], realwrite[14]});
Register_8bit R15(clk, rst, WriteData, regout15, {realwrite[15], realwrite[15]});
//$s0~$s7
Register_8bit R16(clk, rst, WriteData, regout16, {realwrite[16], realwrite[16]});
Register_8bit R17(clk, rst, WriteData, regout17, {realwrite[17], realwrite[17]});
Register_8bit R18(clk, rst, WriteData, regout18, {realwrite[18], realwrite[18]});
Register_8bit R19(clk, rst, WriteData, regout19, {realwrite[19], realwrite[19]});
Register_8bit R20(clk, rst, WriteData, regout20, {realwrite[20], realwrite[20]});
Register_8bit R21(clk, rst, WriteData, regout21, {realwrite[21], realwrite[21]});
Register_8bit R22(clk, rst, WriteData, regout22, {realwrite[22], realwrite[22]});
Register_8bit R23(clk, rst, WriteData, regout23, {realwrite[23], realwrite[23]});
//$t8~$t9
Register_8bit R24(clk, rst, WriteData, regout24, {realwrite[24], realwrite[24]});
Register_8bit R25(clk, rst, WriteData, regout25, {realwrite[25], realwrite[25]});
//$k0~$k1
Register_8bit R26(clk, rst, WriteData, regout26, {realwrite[26], realwrite[26]});
Register_8bit R27(clk, rst, WriteData, regout27, {realwrite[27], realwrite[27]});
//$gp
Register_8bit R28(clk, rst, WriteData, regout28, {realwrite[28], realwrite[28]});
//$sp
Register_8bit R29(clk, rst, WriteData, regout29, {realwrite[29], realwrite[29]});
//$fp
Register_8bit R30(clk, rst, WriteData, regout30, {realwrite[30], realwrite[30]});
//$ra
Register_8bit R31(clk, rst, WriteData, regout31, {realwrite[31], realwrite[31]});
  
  
           
//ReadData1
MUX32to1_8bit RD1(regout0, regout1, regout2, regout3, regout4, regout5, regout6, regout7, regout8, regout9, regout10, regout11, regout12, regout13, regout14, regout15, regout16, regout17, regout18, regout19, regout20, regout21, regout22, regout23, regout24, regout25, regout26, regout27, regout28, regout29, regout30, regout31, ReadData1, ReadRegister1);
//ReadData2
MUX32to1_8bit RD2(regout0, regout1, regout2, regout3, regout4, regout5, regout6, regout7, regout8, regout9, regout10, regout11, regout12, regout13, regout14, regout15, regout16, regout17, regout18, regout19, regout20, regout21, regout22, regout23, regout24, regout25, regout26, regout27, regout28, regout29, regout30, regout31, ReadData2, ReadRegister2);

endmodule

module MUX4to1_1bit(
  input0,
  input1,
  input2,
  input3,
  output0,
  sel,
  on
);

input input0, 
      input1,
      input2,
      input3;
input [1:0]sel;
input on;
output output0;

wire [3:0]w1;

and a0(w1[0], input0, ~sel[0], ~sel[1], on);
and a1(w1[1], input1, sel[0], ~sel[1], on);
and a2(w1[2], input2, ~sel[0], sel[1], on);
and a3(w1[3], input3, sel[0], sel[1], on);

or o0(output0, w1[0], w1[1], w1[2], w1[3]);

endmodule

module MUX4to1_8bit(
  input0,
  input1,
  input2,
  input3,
  output0,
  sel
);

input [7:0]input0, input1, input2, input3;
input [1:0]sel;
output [7:0]output0;

MUX4to1_1bit m0(input0[0], input1[0], input2[0], input3[0], output0[0], sel, 1'b1);
MUX4to1_1bit m1(input0[1], input1[1], input2[1], input3[1], output0[1], sel, 1'b1);
MUX4to1_1bit m2(input0[2], input1[2], input2[2], input3[2], output0[2], sel, 1'b1);
MUX4to1_1bit m3(input0[3], input1[3], input2[3], input3[3], output0[3], sel, 1'b1);
MUX4to1_1bit m4(input0[4], input1[4], input2[4], input3[4], output0[4], sel, 1'b1);
MUX4to1_1bit m5(input0[5], input1[5], input2[5], input3[5], output0[5], sel, 1'b1);
MUX4to1_1bit m6(input0[6], input1[6], input2[6], input3[6], output0[6], sel, 1'b1);
MUX4to1_1bit m7(input0[7], input1[7], input2[7], input3[7], output0[7], sel, 1'b1);



endmodule


module MUX8to1_1bit(
  input0,
  input1,
  input2,
  input3,
  input4,
  input5,
  input6,
  input7,
  output0,
  sel,
  on
);

input input0,
      input1,
      input2,
      input3,
      input4,
      input5,
      input6,
      input7;
input [2:0]sel;
input on;
output output0;


wire [1:0]w1;
wire [1:0]on1;
and a0(on1[0], ~sel[2], on);
and a1(on1[1], sel[2], on);

MUX4to1_1bit m0(input0, input1, input2, input3, w1[0], sel[1:0], on1[0]);
MUX4to1_1bit m1(input4, input5, input6, input7, w1[1], sel[1:0], on1[1]);

or o1(output0, w1[0], w1[1]);

endmodule

module MUX16to1_1bit(
  input0,
  input1,
  input2,
  input3,
  input4,
  input5,
  input6,
  input7,
  input8,
  input9,
  input10,
  input11,
  input12,
  input13,
  input14,
  input15,
  output0,
  sel,
  on
);

input input0,
      input1,
      input2,
      input3,
      input4,
      input5,
      input6,
      input7,
      input8,
      input9,
      input10,
      input11,
      input12,
      input13,
      input14,
      input15;
input [3:0]sel;
input on;
output output0;

wire [1:0]w1;
wire [1:0]on1;
and a0(on1[0], ~sel[3], on);
and a1(on1[1], sel[3], on);

MUX8to1_1bit m0(input0, input1, input2, input3, input4, input5, input6, input7, w1[0], sel[2:0], on1[0]);
MUX8to1_1bit m1(input8, input9, input10, input11, input12, input13, input14, input15, w1[1], sel[2:0], on1[1]);

or o1(output0, w1[0], w1[1]);

endmodule


module MUX32to1_1bit(
  input0,
  input1,
  input2,
  input3,
  input4,
  input5,
  input6,
  input7,
  input8,
  input9,
  input10,
  input11,
  input12,
  input13,
  input14,
  input15,
  input16,
  input17,
  input18,
  input19,
  input20,
  input21,
  input22,
  input23,
  input24,
  input25,
  input26,
  input27,
  input28,
  input29,
  input30,
  input31,
  output0,
  sel,
  on
);

input input0,
      input1,
      input2,
      input3,
      input4,
      input5,
      input6,
      input7,
      input8,
      input9,
      input10,
      input11,
      input12,
      input13,
      input14,
      input15,
      input16,
      input17,
      input18,
      input19,
      input20,
      input21,
      input22,
      input23,
      input24,
      input25,
      input26,
      input27,
      input28,
      input29,
      input30,
      input31;
input [4:0]sel;
input on;
output output0;

wire [1:0]w1;
wire [1:0]on1;
and a0(on1[0], ~sel[4], on);
and a1(on1[1], sel[4], on);

MUX16to1_1bit m0(input0, input1, input2, input3, input4, input5, input6, input7, input8, input9, input10, input11, input12, input13, input14, input15, w1[0], sel[3:0], on1[0]);
MUX16to1_1bit m1(input16, input17, input18, input19, input20, input21, input22, input23, input24, input25, input26, input27, input28, input29, input30, input31, w1[1], sel[3:0], on1[1]);

or o1(output0, w1[0], w1[1]);

endmodule

module MUX32to1_8bit(
    input0,
  input1,
  input2,
  input3,
  input4,
  input5,
  input6,
  input7,
  input8,
  input9,
  input10,
  input11,
  input12,
  input13,
  input14,
  input15,
  input16,
  input17,
  input18,
  input19,
  input20,
  input21,
  input22,
  input23,
  input24,
  input25,
  input26,
  input27,
  input28,
  input29,
  input30,
  input31,
  output1,
  sel
);

input [7:0]input0,
      input1,
      input2,
      input3,
      input4,
      input5,
      input6,
      input7,
      input8,
      input9,
      input10,
      input11,
      input12,
      input13,
      input14,
      input15,
      input16,
      input17,
      input18,
      input19,
      input20,
      input21,
      input22,
      input23,
      input24,
      input25,
      input26,
      input27,
      input28,
      input29,
      input30,
      input31;
input [4:0]sel;
output [7:0]output1;


MUX32to1_1bit m0(input0[0], input1[0], input2[0], input3[0], input4[0], input5[0], input6[0], input7[0], input8[0], input9[0], input10[0], input11[0], input12[0], input13[0], input14[0], input15[0], input16[0], input17[0], input18[0], input19[0], input20[0], input21[0], input22[0], input23[0], input24[0], input25[0], input26[0], input27[0], input28[0], input29[0], input30[0], input31[0], output1[0], sel, 1'b1);
MUX32to1_1bit m1(input0[1], input1[1], input2[1], input3[1], input4[1], input5[1], input6[1], input7[1], input8[1], input9[1], input10[1], input11[1], input12[1], input13[1], input14[1], input15[1], input16[1], input17[1], input18[1], input19[1], input20[1], input21[1], input22[1], input23[1], input24[1], input25[1], input26[1], input27[1], input28[1], input29[1], input30[1], input31[1], output1[1], sel, 1'b1);
MUX32to1_1bit m2(input0[2], input1[2], input2[2], input3[2], input4[2], input5[2], input6[2], input7[2], input8[2], input9[2], input10[2], input11[2], input12[2], input13[2], input14[2], input15[2], input16[2], input17[2], input18[2], input19[2], input20[2], input21[2], input22[2], input23[2], input24[2], input25[2], input26[2], input27[2], input28[2], input29[2], input30[2], input31[2], output1[2], sel, 1'b1);
MUX32to1_1bit m3(input0[3], input1[3], input2[3], input3[3], input4[3], input5[3], input6[3], input7[3], input8[3], input9[3], input10[3], input11[3], input12[3], input13[3], input14[3], input15[3], input16[3], input17[3], input18[3], input19[3], input20[3], input21[3], input22[3], input23[3], input24[3], input25[3], input26[3], input27[3], input28[3], input29[3], input30[3], input31[3], output1[3], sel, 1'b1);
MUX32to1_1bit m4(input0[4], input1[4], input2[4], input3[4], input4[4], input5[4], input6[4], input7[4], input8[4], input9[4], input10[4], input11[4], input12[4], input13[4], input14[4], input15[4], input16[4], input17[4], input18[4], input19[4], input20[4], input21[4], input22[4], input23[4], input24[4], input25[4], input26[4], input27[4], input28[4], input29[4], input30[4], input31[4], output1[4], sel, 1'b1);
MUX32to1_1bit m5(input0[5], input1[5], input2[5], input3[5], input4[5], input5[5], input6[5], input7[5], input8[5], input9[5], input10[5], input11[5], input12[5], input13[5], input14[5], input15[5], input16[5], input17[5], input18[5], input19[5], input20[5], input21[5], input22[5], input23[5], input24[5], input25[5], input26[5], input27[5], input28[5], input29[5], input30[5], input31[5], output1[5], sel, 1'b1);
MUX32to1_1bit m6(input0[6], input1[6], input2[6], input3[6], input4[6], input5[6], input6[6], input7[6], input8[6], input9[6], input10[6], input11[6], input12[6], input13[6], input14[6], input15[6], input16[6], input17[6], input18[6], input19[6], input20[6], input21[6], input22[6], input23[6], input24[6], input25[6], input26[6], input27[6], input28[6], input29[6], input30[6], input31[6], output1[6], sel, 1'b1);
MUX32to1_1bit m7(input0[7], input1[7], input2[7], input3[7], input4[7], input5[7], input6[7], input7[7], input8[7], input9[7], input10[7], input11[7], input12[7], input13[7], input14[7], input15[7], input16[7], input17[7], input18[7], input19[7], input20[7], input21[7], input22[7], input23[7], input24[7], input25[7], input26[7], input27[7], input28[7], input29[7], input30[7], input31[7], output1[7], sel, 1'b1);



endmodule


module DEC5to32(in, out);
input [4:0] in;
output [31:0] out;
wire [15:0] DecodedData;
wire Nin;


assign Nin = ~in[4];
DEC4to16 Dec4(in[3:0], DecodedData[15:0]);

and(out[31], in[4], DecodedData[15]);
and(out[30], in[4], DecodedData[14]);
and(out[29], in[4], DecodedData[13]);
and(out[28], in[4], DecodedData[12]);
and(out[27], in[4], DecodedData[11]);
and(out[26], in[4], DecodedData[10]);
and(out[25], in[4], DecodedData[9]);
and(out[24], in[4], DecodedData[8]);
and(out[23], in[4], DecodedData[7]);
and(out[22], in[4], DecodedData[6]);
and(out[21], in[4], DecodedData[5]);
and(out[20], in[4], DecodedData[4]);
and(out[19], in[4], DecodedData[3]);
and(out[18], in[4], DecodedData[2]);
and(out[17], in[4], DecodedData[1]);
and(out[16], in[4], DecodedData[0]);

and(out[15], Nin, DecodedData[15]);
and(out[14], Nin, DecodedData[14]);
and(out[13], Nin, DecodedData[13]);
and(out[12], Nin, DecodedData[12]);
and(out[11], Nin, DecodedData[11]);
and(out[10], Nin, DecodedData[10]);
and(out[9], Nin, DecodedData[9]);
and(out[8], Nin, DecodedData[8]);
and(out[7], Nin, DecodedData[7]);
and(out[6], Nin, DecodedData[6]);
and(out[5], Nin, DecodedData[5]);
and(out[4], Nin, DecodedData[4]);
and(out[3], Nin, DecodedData[3]);
and(out[2], Nin, DecodedData[2]);
and(out[1], Nin, DecodedData[1]);
and(out[0], Nin, DecodedData[0]);

endmodule


module DEC4to16(in, out);
input [3:0] in;
output [15:0] out;
wire [7:0] DecodedData;
wire Nin;

assign Nin = ~in[3];
DEC3to8 Dec3(in[2:0], DecodedData[7:0]);

and(out[15], in[3], DecodedData[7]);
and(out[14], in[3], DecodedData[6]);
and(out[13], in[3], DecodedData[5]);
and(out[12], in[3], DecodedData[4]);
and(out[11], in[3], DecodedData[3]);
and(out[10], in[3], DecodedData[2]);
and(out[9], in[3], DecodedData[1]);
and(out[8], in[3], DecodedData[0]);

and(out[7], Nin, DecodedData[7]);
and(out[6], Nin, DecodedData[6]);
and(out[5], Nin, DecodedData[5]);
and(out[4], Nin, DecodedData[4]);
and(out[3], Nin, DecodedData[3]);
and(out[2], Nin, DecodedData[2]);
and(out[1], Nin, DecodedData[1]);
and(out[0], Nin, DecodedData[0]);


endmodule


module DEC3to8(in, out);
input [2:0] in;
output [7:0] out;
wire [3:0] DecodedData;
wire Nin;
assign Nin = ~in[2];
DEC2to4 Dec2(in[1:0], DecodedData[3:0]);


and(out[7], in[2], DecodedData[3]);
and(out[6], in[2], DecodedData[2]);
and(out[5], in[2], DecodedData[1]);
and(out[4], in[2], DecodedData[0]);


and(out[3], Nin, DecodedData[3]);
and(out[2], Nin, DecodedData[2]);
and(out[1], Nin, DecodedData[1]);
and(out[0], Nin, DecodedData[0]);

endmodule

module DEC2to4(in, out);
input [1:0] in;
output [3:0] out;
wire [1:0] Nin;

assign Nin = ~in;

and a1(out[0], Nin[1], Nin[0]);
and a2(out[1], Nin[1], in[0]);
and a3(out[2], in[1], Nin[0]);
and a4(out[3], in[1], in[0]);

endmodule